/***********************************
 * Abstract Base Class for all windows in the application
 ***/
class Wnd
{
	friend class Application;
public:
	HWND hWnd;
	Wnd();
	virtual ~Wnd();

	BOOL ShowWindow(int nCmdShow) {return ::ShowWindow(hWnd, nCmdShow);}
	BOOL UpdateWindow() {return ::UpdateWindow(hWnd);}
	HWND GetParent(){return ::GetParent(hWnd);}
protected:
	WndController* pWndController;
	bool isWindowCreated;

	/* The following 4 virtual functions
	   allows Base Class to do the Register and Creating  */
	virtual BOOL isWndClassRegistered() = 0;	// flag to indicates whether the WindowClass is registered
	virtual void setWndClassRegistered() = 0;	// set the flag to TRUE if the WindowClass is registered
	virtual LPCWSTR getWndClassName() = 0;		// get the Name of WindowClass
	virtual ATOM MyRegisterClass(HINSTANCE hInstance) = 0;	// Register Function

	/* Check if the WindowClass is Registered, and registered it when needed.
	   Then Create Window.*/
	void MyCreateWindow(LPCTSTR WndText, DWORD dwStyle, 
		int x,  int y ,  int nWidth,  int nHeight,
		HWND hWndParent,  HMENU hMenu,  HINSTANCE hInstance, LPVOID lpParam);

	/* The following function is the WndProc.
	   In this base version just process some of the common used messages
	   and pass the unprocessed messages to the DefWindowProc.
	   However, this function is supposed to be over-write 
	   by sub-classes for more specific works.	*/
	LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
};

/***************************************
 * Base Class: WndController
 * Containing:
 *		Message Process Mapping Table,
 *		Message Process Functions
 * Every window should have a controller, 
 *		which containing several functions to process the messages.
 * Controller should derive from this base class, 
 *		and add new mapping item to Mapping Table.
 ***/
class WndController
{
public:
	WndController();
	MsgMappingTable& GetMsgMappingTable(){return MappingTable;}
protected:
	MsgMappingTable MappingTable;

	//Mapped Function to process transactions
	static LRESULT CALLBACK OnWndDestroy(HWND hWnd, WPARAM wParam, LPARAM lParam);
};